<html>
<head><meta charset="utf-8"><title>NonZeroLayout: is this too heavyhanded? · t-libs/wg-allocators · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/197181-t-libs/wg-allocators/index.html">t-libs/wg-allocators</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/197181-t-libs/wg-allocators/topic/NonZeroLayout.3A.20is.20this.20too.20heavyhanded.3F.html">NonZeroLayout: is this too heavyhanded?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="188666476"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/197181-t-libs/wg-allocators/topic/NonZeroLayout%3A%20is%20this%20too%20heavyhanded%3F/near/188666476" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/197181-t-libs/wg-allocators/topic/NonZeroLayout.3A.20is.20this.20too.20heavyhanded.3F.html#188666476">(Feb 20 2020 at 18:54)</a>:</h4>
<p>Raising requirements to the type level is generally a good thing. But especially given that manual allocation is inherently an <code>unsafe</code> operation, I'm wondering if it's a bit heavy-handed and not really necessary.</p>
<p>Rust does pride itself on zero-cost abstractions and pick-your-costs, but moreso than that, I think Rust also is useful because it is _safe by default_. IOW, the first API you tend to reach for should be the safest to use; for the case of allocators, that would mean requiring them to handle zero-sized allocations transparently, rather than pushing that to the user.</p>
<p>Going through the list of <code>Alloc</code>-friends traits in alloc-wg, per that concept, the available methods that could reasonably need to handle zero-sized "allocations", or can pretend they don't exist would be:</p>
<ul>
<li><code>alloc(Layout)</code></li>
<li><code>alloc_zeroed(Layout)</code></li>
<li><code>dealloc(ptr, Layout)</code></li>
<li><code>realloc(ptr, Layout, Layout)</code></li>
<li><code>grow_in_place(ptr, Layout, usize)</code></li>
<li><code>shrink_in_place(ptr, Layout, usize)</code></li>
</ul>
<p>i.e. all of them could fairly reasonably be expected to work transparently with zero sized allocations.</p>



<a name="188667583"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/197181-t-libs/wg-allocators/topic/NonZeroLayout%3A%20is%20this%20too%20heavyhanded%3F/near/188667583" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/197181-t-libs/wg-allocators/topic/NonZeroLayout.3A.20is.20this.20too.20heavyhanded.3F.html#188667583">(Feb 20 2020 at 19:06)</a>:</h4>
<p>What exactly is the cost of requiring allocator handles to handle zero sized allocations, even if the underlying allocator doesn't handle them?</p>
<p>In the common case (<code>T: Sized</code>), the cost is trivially zero, as the compiler should easily optimize out the check against a constant layout.</p>
<p>In the fully dynamic case (e.g. <code>[T; ?N]</code> or a fully unknown <code>T</code>, like for <code>Box</code>), <em>someone</em> is going to have to do the check, whether it's internal to the allocator or external. It's actually probably cheaper timewise for e.g. a bump allocator to actually "allocate" even in the zero sized case, and doing a call to the allocator allows e.g. tracing allocators to trace even the zero sized allocations.</p>
<p>The only case where avoiding this check via an <code>unsafe</code> assertion would avoid the cost of said branch would be if a) <code>alloc</code> is <code>#[inline(never)]</code> for code size (in which code size &gt; speed), or b) a type like my <a href="https://docs.rs/slice-dst/1.1.0/slice_dst/struct.SliceWithHeader.html" target="_blank" title="https://docs.rs/slice-dst/1.1.0/slice_dst/struct.SliceWithHeader.html"><code>SliceWithHeader</code></a> which is both <code>?Sized</code> but has a guaranteed minimum size (and these types aren't even safe to create in current Rust). _Perhaps_ trait objects could be argued to fall into this category, but those are allocated first as sized types and then unsized, not allocated as <code>?Sized</code> types to begin with.</p>



<a name="188668031"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/197181-t-libs/wg-allocators/topic/NonZeroLayout%3A%20is%20this%20too%20heavyhanded%3F/near/188668031" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/197181-t-libs/wg-allocators/topic/NonZeroLayout.3A.20is.20this.20too.20heavyhanded.3F.html#188668031">(Feb 20 2020 at 19:11)</a>:</h4>
<p>And in the case where the branch can be statically determined to be not taken but the compiler can't figure it out, something like <code>assume(layout.size() &gt; 0)</code> can be used to recover the invariant. (<a href="https://play.rust-lang.org/?version=nightly&amp;mode=release&amp;edition=2018&amp;gist=973976bd4402fac98a11ca6173f6e2f0" target="_blank" title="https://play.rust-lang.org/?version=nightly&amp;mode=release&amp;edition=2018&amp;gist=973976bd4402fac98a11ca6173f6e2f0">playground</a>, <a href="https://rust.godbolt.org/z/_tM7kf" target="_blank" title="https://rust.godbolt.org/z/_tM7kf">godbolt</a>)</p>



<a name="188668286"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/197181-t-libs/wg-allocators/topic/NonZeroLayout%3A%20is%20this%20too%20heavyhanded%3F/near/188668286" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christopher Durham <a href="https://rust-lang.github.io/zulip_archive/stream/197181-t-libs/wg-allocators/topic/NonZeroLayout.3A.20is.20this.20too.20heavyhanded.3F.html#188668286">(Feb 20 2020 at 19:14)</a>:</h4>
<p>Even if default methods are provided <a href="https://github.com/rust-lang/wg-allocators/issues/38#issuecomment-588652418" target="_blank" title="https://github.com/rust-lang/wg-allocators/issues/38#issuecomment-588652418">in the correct order, from the least to the most generally applicable</a>, I don't think the API complexity of having <code>NonZeroLayout</code> on top of <code>Layout</code> is really worth it.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>